/**
 * src/utils/ErrorHandler.ts
 * 统一错误处理器
 */

import * as vscode from 'vscode';

/**
 * 错误级别
 */
export enum ErrorLevel {
    Info = 'info',
    Warning = 'warning',
    Error = 'error',
    Critical = 'critical'
}

/**
 * 错误处理配置
 */
export interface ErrorHandlerConfig {
    showNotification?: boolean;  // 是否显示 VSCode 通知
    logToConsole?: boolean;      // 是否输出到控制台
    level?: ErrorLevel;          // 错误级别
}

/**
 * 全局错误处理器
 */
export class ErrorHandler {
    
    private static readonly DEFAULT_CONFIG: ErrorHandlerConfig = {
        showNotification: true,
        logToConsole: true,
        level: ErrorLevel.Error
    };

    /**
     * 处理错误
     */
    public static handle(error: Error | string, config?: ErrorHandlerConfig): void {
        const finalConfig = { ...this.DEFAULT_CONFIG, ...config };
        const errorMessage = error instanceof Error ? error.message : error;
        const errorStack = error instanceof Error ? error.stack : undefined;

        // 1. 控制台日志
        if (finalConfig.logToConsole) {
            const prefix = `[ErrorHandler][${finalConfig.level}]`;
            console.error(prefix, errorMessage);
            if (errorStack) {
                console.error('Stack:', errorStack);
            }
        }

        // 2. VSCode 通知
        if (finalConfig.showNotification) {
            const displayMessage = `TestAgent: ${errorMessage}`;
            
            switch (finalConfig.level) {
                case ErrorLevel.Info:
                    vscode.window.showInformationMessage(displayMessage);
                    break;
                case ErrorLevel.Warning:
                    vscode.window.showWarningMessage(displayMessage);
                    break;
                case ErrorLevel.Error:
                case ErrorLevel.Critical:
                    vscode.window.showErrorMessage(displayMessage);
                    break;
            }
        }
    }

    /**
     * 包装异步函数,自动捕获错误
     */
    public static async wrapAsync<T>(
        fn: () => Promise<T>,
        errorMessage: string = 'Operation failed',
        config?: ErrorHandlerConfig
    ): Promise<T | undefined> {
        try {
            return await fn();
        } catch (error) {
            const finalMessage = error instanceof Error 
                ? `${errorMessage}: ${error.message}` 
                : errorMessage;
            
            this.handle(finalMessage, config);
            return undefined;
        }
    }

    /**
     * 包装同步函数,自动捕获错误
     */
    public static wrapSync<T>(
        fn: () => T,
        errorMessage: string = 'Operation failed',
        config?: ErrorHandlerConfig
    ): T | undefined {
        try {
            return fn();
        } catch (error) {
            const finalMessage = error instanceof Error 
                ? `${errorMessage}: ${error.message}` 
                : errorMessage;
            
            this.handle(finalMessage, config);
            return undefined;
        }
    }
}
